TVI – Transformed Vegetation Index

TVI is a transformed vegetation index derived from NDVI to enhance the separation of medium-to-high vegetation cover and reduce saturation effects. It applies a square-root transform to NDVI to stretch the mid-range values.

1. Scientific Definition

The Transformed Vegetation Index (TVI) is a simple transformation of the Normalized Difference Vegetation Index (NDVI). It is designed to improve the contrast between different vegetation densities, especially in medium and dense canopies, by applying a non-linear (square-root) function.

Formula

First, NDVI is computed as:

NDVI = (NIR − Red) / (NIR + Red)

Then TVI is defined as:

TVI = sqrt(NDVI + 0.5) Dimensionless (approx. 0 to 1.2)

Where:

  • NIR – Near InfraRed reflectance
  • Red – Red band reflectance
  • sqrt – square-root transform that stretches NDVI mid-range

Typical Interpretation

TVI values do not have as widely standardized thresholds as NDVI, but a typical interpretation (assuming NDVI between –0.2 and +1) can be:

TVI Range (approx.) Interpretation (linked to NDVI)
< 0.6 Water, clouds, snow, bare soil, built-up or very sparse vegetation (NDVI ≤ 0.2)
0.6 – 0.8 Moderate vegetation cover (grasslands, shrubs, mixed cover)
> 0.8 Dense and healthy vegetation (croplands, forests, high biomass)

Key Applications

  • Enhancing contrast in medium-to-high vegetation cover areas
  • Complementing NDVI in regions where NDVI tends to saturate
  • Crop monitoring and vegetation vigour assessment
  • Supporting classification and change detection workflows

2. Data & Bands for TVI

Common Sensors & Bands

  • Sentinel-2 (ESA) – 10 m
    • Red: B4 (~665 nm)
    • NIR: B8 (~842 nm)
  • Landsat 8/9 OLI – 30 m
    • Red: B4
    • NIR: B5

Good Practice

  • Use atmospherically corrected surface reflectance products.
  • Filter images by cloud percentage and apply cloud masks when available.
  • Clip the final TVI raster to your Area of Interest (AOI) before exporting.
  • Use consistent dates/time windows for time-series or multi-year analyses.

Palette Suggestion

A TVI color palette can follow a similar scheme to NDVI: [ "#440154", "#3b528b", "#21908c", "#5dc963", "#fde725" ]

3. Google Earth Engine Code – TVI for Any AOI

Steps: open code.earthengine.google.com → New Script → paste the code → draw your AOI as geometry on the map → click Run. Then export TVI as GeoTIFF to Google Drive.

// TVI (Transformed Vegetation Index) for any Area of Interest (AOI) using Sentinel-2 SR
// --------------------------------------------------------------------
// 1) Go to: https://code.earthengine.google.com
// 2) Click "New Script" and paste this code.
// 3) On the map: draw your AOI (Polygon/Rectangle).
//    It will appear as a variable named 'geometry' in the left panel.
// 4) Click "Run" to display TVI.
// 5) In the Tasks tab, click "Run" to export TVI to Google Drive.

// --------------------------------------------------------------------
// 1. Define Area of Interest (AOI)
// --------------------------------------------------------------------
// Use the geometry you draw on the map:
var roi = geometry;  // Make sure a 'geometry' object exists in the left panel

// Center the map on the AOI
Map.centerObject(roi, 11);

// --------------------------------------------------------------------
// 2. Define time range
//    Adjust dates according to your study period
// --------------------------------------------------------------------
var startDate = '2023-01-01';
var endDate   = '2023-12-31';

// --------------------------------------------------------------------
// 3. Load Sentinel-2 Surface Reflectance collection
// --------------------------------------------------------------------
var s2 = ee.ImageCollection('COPERNICUS/S2_SR')
  .filterBounds(roi)
  .filterDate(startDate, endDate)
  .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20))
  .select(['B4','B8']);  // Red, NIR

// Create a median composite and clip to AOI
var image = s2.median().clip(roi);

// --------------------------------------------------------------------
// 4. Compute NDVI
//    NDVI = (NIR - Red) / (NIR + Red)
// --------------------------------------------------------------------
var ndvi = image.normalizedDifference(['B8', 'B4']).rename('NDVI');

// --------------------------------------------------------------------
// 5. Compute TVI
//    TVI = sqrt(NDVI + 0.5)
// --------------------------------------------------------------------
var tvi = ndvi.add(0.5).sqrt().rename('TVI');

// --------------------------------------------------------------------
// 6. Visualization on the map
// --------------------------------------------------------------------
var tviVis = {
  min: 0.0,
  max: 1.2,
  palette: [
    '#440154', // low
    '#3b528b',
    '#21908c',
    '#5dc963',
    '#fde725'  // high
  ]
};

// Add TVI layer to the map
Map.addLayer(tvi, tviVis, 'TVI (Sentinel-2)', true);

// Optionally, also show a true color composite for context
var s2_rgb = ee.ImageCollection('COPERNICUS/S2_SR')
  .filterBounds(roi)
  .filterDate(startDate, endDate)
  .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20))
  .select(['B4','B3','B2'])  // RGB
  .median()
  .clip(roi);

Map.addLayer(s2_rgb, {min: 0, max: 3000}, 'True Color (RGB)', false);

// --------------------------------------------------------------------
// 7. Export TVI as GeoTIFF to Google Drive
// --------------------------------------------------------------------
Export.image.toDrive({
  image: tvi,
  description: 'TVI_Export',
  fileNamePrefix: 'TVI_Export',
  region: roi,
  scale: 10,       // Sentinel-2 resolution
  crs: 'EPSG:4326',
  maxPixels: 1e13
});

// End of script